#pragma once
#include <comutil.h>
#include "shockwaveflash1.h"

namespace FlashWrapper
{
	class FlashBase :
		public IOleClientSite,
		public IOleInPlaceSiteWindowless,
		public IOleInPlaceFrame,
		public IStorage,
		public IDispatch
	{
	public:
		FlashBase(HINSTANCE hInst, HWND hContainer);
		virtual ~FlashBase(void);

		BOOL Init();

	public:
		//IUnknown
		virtual HRESULT STDMETHODCALLTYPE QueryInterface( 
			/* [in] */ REFIID riid,
			/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject);

		virtual ULONG STDMETHODCALLTYPE AddRef( void){return 1;};
		virtual ULONG STDMETHODCALLTYPE Release( void){return 1;};

		//IOleClientSite
		virtual HRESULT STDMETHODCALLTYPE SaveObject() { return E_NOTIMPL; }
		virtual HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk){ return E_NOTIMPL; }
		virtual HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer){*ppContainer = NULL;return E_NOINTERFACE;}
		virtual HRESULT STDMETHODCALLTYPE ShowObject(){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL fShow){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(){return E_NOTIMPL;}

		//IOleInPlaceSite
		virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND * lphwnd);
		virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode){ return E_NOTIMPL; }
		virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(){ return S_OK; }
		virtual HRESULT STDMETHODCALLTYPE OnUIActivate(){ return S_OK; }

		virtual HRESULT STDMETHODCALLTYPE GetWindowContext(LPOLEINPLACEFRAME * lplpFrame,LPOLEINPLACEUIWINDOW * lplpDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo);
		virtual HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtent){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect){return S_OK;}

		//IOleInPlaceSiteEx
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL  *pfNoRedraw, DWORD dwFlags);
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL fNoRedraw){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE RequestUIActivate(void){return S_FALSE;}

		//IOleInPlaceSiteWindowless
		virtual HRESULT STDMETHODCALLTYPE CanWindowlessActivate( void){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE GetCapture( void){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE SetCapture( BOOL fCapture){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE GetFocus( void){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE SetFocus( BOOL fFocus){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE GetDC(LPCRECT pRect,DWORD grfFlags,HDC *phDC){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE ReleaseDC( HDC hDC){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE InvalidateRect( LPCRECT pRect,BOOL fErase);
		virtual HRESULT STDMETHODCALLTYPE InvalidateRgn( HRGN hRGN,BOOL fErase){return S_OK;} 
		virtual HRESULT STDMETHODCALLTYPE ScrollRect( INT dx,INT dy,LPCRECT pRectScroll,LPCRECT pRectClip){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE AdjustRect( LPRECT prc){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE OnDefWindowMessage( UINT msg,WPARAM wParam,LPARAM lParam,LRESULT *plResult){return S_FALSE;}

		//IOleInPlaceFrame
		virtual HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS pborderwidths){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE RemoveMenus(HMENU hmenuShared){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetStatusText(LPCOLESTR pszStatusText){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD wID){return E_NOTIMPL;}

		//IStorage
		virtual HRESULT STDMETHODCALLTYPE CreateStream(const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OpenStream(const WCHAR * pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE CreateStorage(const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage **ppstg){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OpenStorage(const WCHAR * pwcsName, IStorage * pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE CopyTo(DWORD ciidExclude, IID const *rgiidExclude, SNB snbExclude,IStorage *pstgDest){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE MoveElementTo(const OLECHAR *pwcsName,IStorage * pstgDest, const OLECHAR *pwcsNewName, DWORD grfFlags){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Revert(){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE EnumElements(DWORD reserved1, void * reserved2, DWORD reserved3, IEnumSTATSTG ** ppenum){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE DestroyElement(const OLECHAR *pwcsName){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE RenameElement(const WCHAR *pwcsOldName, const WCHAR *pwcsNewName){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetElementTimes(const WCHAR *pwcsName, FILETIME const *pctime, FILETIME const *patime, FILETIME const *pmtime){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetClass(REFCLSID clsid){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE SetStateBits(DWORD grfStateBits, DWORD grfMask){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG * pstatstg, DWORD grfStatFlag){return E_NOTIMPL;}

		//IDispatch
		virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo * *ppTInfo){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr);

		//IAdobeShockwaveFlashEvent
		virtual HRESULT STDMETHODCALLTYPE OnReadyStateChange(long newState){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE OnProgress(long percentDone){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE FSCommand(_bstr_t command, _bstr_t args){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE FlashCall (_bstr_t request ,VARIANT * varResult);

	public:
		virtual void SetSize( LONG nWidth,LONG nHeight );
		virtual void Destroy();
		void Play(LPCTSTR pszUrl);

	private:
		HINSTANCE m_hInst;
		HWND m_hContainer;
		RECT m_rectContainer;
		int m_nResID;

		CComPtr<IDispatch>						m_spFlashDispatch;
		CComPtr<IOleObject>						m_spOleObject;
		CComPtr<IViewObjectEx>					m_spViewObjectEx;
		CComPtr<IOleInPlaceObject>				m_spInPlaceObject;
		CComPtr<IOleInPlaceObjectWindowless>	m_spInPlaceObjectWindowless;
		CComPtr<IConnectionPointContainer>		m_spConnPoitContainer;
		CComPtr<IConnectionPoint>				m_spConnPoint;

		CShockwaveflash1* m_spFlashControl;
		DWORD m_dwConnPointCookie;

		HWND m_hAcitvex;
	};
}
